home *** CD-ROM | disk | FTP | other *** search
- #include "util.h"
- #include "conf.h"
- #include <sys/stat.h>
- #include "ll_log.h"
-
- /* Package for logging entries into files */
-
- /* David H. Crocker, Dept. of Electrical Engineering */
- /* University of Delaware; October 1979 */
-
- /* Failure to open a log file, other than due to its being busy,
- * causes the fd associated with ll_struct to be set to -1.
- * Later calls then result in a no-op, except for openllog & closellog
- */
-
- /*
- * Modified to use 4.2BSD's O_APPEND mode unless the file is in cycle mode
- * Peter Collinson UKC March 1987
- * Probably would be better to totally rewrite this, but that seems
- * a little dangerous and is probably not good engineering practice
- */
- #ifdef V4_2BSD
- #include <sys/file.h>
- #endif
-
- #define _LLRETRY 5 /* number of retries if log locked */
- #define _LLSLEEP 5 /* time between tries */
-
-
- #define SHORTIM 0 /* Short time format */
- #define LONGTIM 1 /* Long time format */
- #define _LLDIDC 0200 /* Already did cycle, this opening */
-
- extern char *strdup ();
- extern time_t time();
- extern int errno;
-
- LOCFUN ll_tmout(), ll_cycle(), ll_size(), ll_time();
-
- LOCVAR int errno_save;
-
- LOCVAR char
- _cycling[] = "\n\n*** CYCLING ***\n",
- _cycled[] = "*** CYCLED ***\n";
-
- /* ******************* LOG OPENING AND CLOSING ******************** */
-
- ll_open (loginfo) /* physically open the file */
- register struct ll_struct *loginfo;
- {
- short retries;
- int opnflg;
-
- if (loginfo -> ll_file == 0 || *(loginfo -> ll_file) == '\0')
- return (loginfo -> ll_fd = NOTOK);
- /* no pathname => no place to log */
-
- #ifdef V4_2BSD
- opnflg = (loginfo -> ll_stat & LLOGCYC) ? O_WRONLY : (O_WRONLY|O_APPEND);
- #else
- opnflg = 1;
- #endif
- if (loginfo -> ll_fd <= 0) /* now closed; ALWAYS try */
- for (retries = _LLRETRY;
- (loginfo -> ll_fd = open (loginfo -> ll_file, opnflg)) <= 0;
- sleep (_LLSLEEP))
- { /* exclusive & write access */
- if (errno != 26 || /* not simply busy */
- !(loginfo -> ll_stat & LLOGWAT) ||
- retries-- <= 0)
- return (loginfo -> ll_fd = NOTOK);
- }
-
- if (loginfo -> ll_timmax <= 0)
- loginfo -> ll_timmax = LLTIMEOUT;
- loginfo -> ll_timer = time((time_t *)0);
- loginfo -> ll_fp = fdopen(loginfo -> ll_fd, "w");
- return (ll_init (loginfo));
- }
-
-
- ll_close (loginfo)
- register struct ll_struct *loginfo;
- { /* maybe close file; always clear fd */
- register int fd;
-
- fd = loginfo -> ll_fd;
- loginfo -> ll_fd = 0; /* clear the fd: erase -1 or handle */
-
- if (loginfo -> ll_stat & _LLDIDC)
- { /* cycled during this open */
- if (fd > 0) /* flag end, from rest of log */
- fwrite (&_cycled[5], sizeof(char), (sizeof _cycled) - 6,
- loginfo -> ll_fp);
- loginfo -> ll_stat &= ~_LLDIDC;
- } /* clear cycled flag */
-
- return ((fd > 0) ? fclose (loginfo -> ll_fp) : NULL);
- /* -1 or 0 => nothing was open */
- }
- /* ********************* LOG INITIALIZATION *********************** */
-
- ll_hdinit (loginfo, pref) /* make header field unique */
- register struct ll_struct *loginfo;
- register char *pref;
- {
- char *curhdr;
- char tmpstr[16];
- static int pid;
-
- if (pid == 0)
- pid = getpid();
-
- if ((curhdr = pref) == (char *) 0)
- if ((curhdr = loginfo -> ll_hdr) == (char *) 0)
- curhdr = "XXXXXX";
-
- (void) sprintf (tmpstr, "%-6.6s%04d", curhdr, pid % 10000);
- /* use last 4 digits of procid */
-
- loginfo -> ll_hdr = strdup (tmpstr);
- ll_close (loginfo); /* start with a clean pointer */
- }
-
- ll_init (loginfo) /* position log [print header] */
- register struct ll_struct *loginfo;
- {
- if (loginfo -> ll_fd < 0)
- return (NOTOK);
-
- #ifdef V4_2BSD
- if ((loginfo -> ll_stat & LLOGCYC) == 0) /*..... don't fseek */
- #endif
- fseek (loginfo -> ll_fp, 0L, 2);
-
-
- if ((loginfo->ll_stat & LLOGCYC) && (ll_cycle (loginfo) < OK))
- return (NOTOK); /* too big and can't cycle */
-
- if ((loginfo -> ll_stat & (LLOGCLS | LLOGTIMED)))
- return (OK); /* don't do header for opening */
-
- if (loginfo -> ll_hdr == (char *) 0) /* give it a place-holder */
- loginfo -> ll_hdr = "";
-
- ll_time (loginfo, LONGTIM);
- errno_save = errno;
- fprintf (loginfo -> ll_fp, "--- OPEN ---(%d)\n", loginfo -> ll_fd);
- errno = errno_save;
-
- return (OK);
- }
-
- /* ********************* DO THE LOGGING *************************** */
-
- /* VARARGS3 */
- ll_log (loginfo, verblev, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a0)
- register struct ll_struct *loginfo;
- int verblev;
- char *format,
- *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9, *a0;
- {
- if (verblev > loginfo -> ll_level)
- return (OK); /* too verbose for this setting */
-
- switch (loginfo -> ll_fd)
- {
- case NOTOK: /* error in its past */
- return (OK);
-
- case 0:
- if (ll_open (loginfo) < OK)
- return (NOTOK); /* couldn't open it properly */
- break;
-
- default:
- if (loginfo -> ll_stat & LLOGTIMED)
- {
- if (ll_tmout(loginfo) < OK)
- return (NOTOK);
- }
- else if (ll_cycle (loginfo) < OK) /* check file size */
- return (NOTOK);
- }
-
- ll_time (loginfo,
- (loginfo -> ll_stat & (LLOGCLS | LLOGTIMED)) ? LONGTIM : SHORTIM);
- errno_save = errno;
- fprintf(loginfo->ll_fp,
- format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a0);
- (void) putc('\n', loginfo->ll_fp);
- errno = errno_save;
-
- fflush(loginfo->ll_fp);
-
- if (loginfo -> ll_stat & LLOGCLS)
- {
- if (ll_close (loginfo) == EOF)
- return (loginfo -> ll_fd = NOTOK);
- }
- /* error or close after each entry */
- return (OK);
- }
-
- /* ********************* INTERNAL ROUTINES ************************ */
-
- LOCFUN
- ll_tmout(loginfo)
- register struct ll_struct *loginfo;
- {
- int temp;
- time_t now;
-
- now = time((time_t *)0);
-
- if ((now - (loginfo->ll_timer)) > (loginfo -> ll_timmax))
- {
-
- if ((temp = ll_close(loginfo)) < OK)
- return(temp);
-
- return (ll_open(loginfo));
- }
-
- return (ll_init(loginfo));
- }
-
-
- LOCFUN
- ll_cycle (loginfo) /* file not within limits => cycle */
- register struct ll_struct *loginfo;
- {
- int stats;
- register int numblocks,
- maxblocks;
-
- if ((maxblocks = loginfo -> ll_msize) <= 0)
- return (OK);
-
- maxblocks *= 25; /* units of 25 blocks */
- numblocks = ll_size (loginfo);
-
- if ((stats = loginfo -> ll_stat) & _LLDIDC)
- { /* different test if already cycled */
- if (numblocks > maxblocks + 1)
- goto endit; /* the sucker REwrote length of file */
- }
- else
- if (numblocks >= maxblocks)
- { /* normal uncycled check */
- if ((stats & LLOGCLS) || !(stats & LLOGCYC))
- { /* give up if one-liner or no cycling */
- endit:
- ll_close (loginfo);
- return (loginfo -> ll_fd = NOTOK);
- }
- /* record status of llog file */
- loginfo -> ll_msize = numblocks / 25;
- loginfo -> ll_stat |= _LLDIDC;
- /* make notes in it & goto beginning */
-
- fseek (loginfo->ll_fp, -20L, 1);
- fwrite(_cycling, sizeof(char), sizeof _cycling - 1,
- loginfo->ll_fp);
- fseek (loginfo->ll_fp, 0L, 0);
- fwrite(_cycled, sizeof(char), sizeof _cycled - 1,
- loginfo->ll_fp);
- }
- return (OK);
- }
- /**/
-
- LOCFUN
- ll_size (loginfo) /* how big is log file? */
- register struct ll_struct *loginfo;
- {
- struct stat llstat;
-
- if(fflush(loginfo->ll_fp) == EOF) /* must show what is buffered too */
- return (0);
- if (fstat(loginfo -> ll_fd, &llstat) < 0)
- return (0);
-
- /*NOSTRICT*/
- return ((st_gsize (&llstat) + 1023L)/1024L);
- }
- /**/
-
- LOCFUN
- ll_time (loginfo, timtype)
- register struct ll_struct *loginfo;
- int timtype;
- { /* record real date/time */
- extern struct tm *localtime ();
- time_t clock;
- register struct tm *tpt;
-
- time (&clock);
- tpt = localtime (&clock);
-
- errno_save = errno;
- switch (timtype)
- {
- case LONGTIM: /* mm/dd hh:mm:ss */
- fprintf (loginfo->ll_fp, "%2d/%2d %2d:%02d:%02d %s: ",
- tpt->tm_mon + 1, tpt->tm_mday, tpt->tm_hour,
- tpt->tm_min, tpt->tm_sec, loginfo -> ll_hdr);
- break;
-
- case SHORTIM: /* mm:ss */
- fprintf (loginfo->ll_fp, "%2d:%02d ", tpt->tm_min, tpt->tm_sec);
- }
- errno = errno_save;
- }
-